package cn.tedu.reflection;

import org.junit.Test;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**本类用于测试暴力反射*/
public class TestReflect2 {
    /**1.通过暴力反射获取私有属性*/
    @Test
    public void getFields() throws NoSuchFieldException, InstantiationException, IllegalAccessException {
        Class<?> clazz = Person.class;
        Field field = clazz.getDeclaredField("name");
//        Field[] fields = clazz.getDeclaredFields("name");

        //根据获取到的私有属性对象获取对应信息
        System.out.println(field.getType());
        System.out.println(field.getType().getName());
        System.out.println(field.getName());
        //想给指定的属性设置值
        field.setAccessible(true);
        //暴力反射!!!需要设置私有资源可见的权限!!!否则报错
        //set(m,n)--m要给哪个对象设置属性值,n要设置的具体的值
        //需要先通过字节码对象创建处目标类Person对象
        Object obj = clazz.newInstance();
        //通过属性对象设置obj(Person类对象)的name属性值为"张大彪"
        field.set(obj,"张大彪");
        System.out.println(field.get(obj));
    }
    /**2.通过暴力反射获取和使用私有方法*/
    @Test
    public void getFunction() throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        Class<?> clazz = new Person().getClass();

        //getDeclaredMethod(m,x,y,z...)
        //m指的是要获取的方法的名字
        //x,y,z指的是要获取方法的参数,注意传入的是字节码对象
        Method method = clazz.getDeclaredMethod("find", String.class);
        //操作前给获取到的方法设置私有可见
        method.setAccessible(true);
        //需要确定那个对象来执行获取到的find(),获取对象
        Object obj = clazz.newInstance();
        //通过invoke()给对象obj执行
        method.invoke(obj,"老王");
        /**暴力反射*/
    }
}
